feat: add async streaming helpers and OTel instrumentation (PY-10)#40
Conversation
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…t, and MCP transports (PY-11) Each class now calls get_tracer() in __init__ and wraps its request chokepoint (_request for REST clients, call_tool for MCP transports) in a start_request_span / start_rpc_span context manager. record_error is called on HyperpingAPIError, httpx timeout, and network failure paths so spans carry ERROR status on failures. All 23 OTel tests now pass; full suite (603 tests) unaffected.
|
CI checks did not appear within 30 minutes. No CI results to report. Verdict: CI_TIMEOUT The monitoring period (30 min) expired before any checks were reported on this branch. This may indicate:
A human should investigate this unusual delay. |
|
Reviewer context (not a merge request): Bundles async streaming helpers and OTel auto-instrumentation (PY-10): httpx2 migration, Where to focus review: The instrumentation refactor in Risks / verify: Heavy re-indentation makes regressions easy to miss; diff line-by-line against CI status: No checks triggered (targets Notes: Appears to be a superset combining #39 + OTel. Reconcile with the #39 stack before merging to avoid conflicting duplicates. |
…t conflicts - pyproject: keep both the cli/typer extras (now on main) and this branch's otel + opentelemetry dev deps; httpx2 dependency retained. - tests/unit/test_mcp_client.py: take main's version (adds MCP write-tool tests; this branch only reformatted one assert). - uv.lock: regenerated against the merged pyproject. Note: this branch's OTel tests (test_otel.py) require the client _tracer wiring that lives in the PY-11 follow-up (PR #40), so they fail standalone here.
- pyproject: keep both main's cli/typer extras and this branch's otel + opentelemetry dev deps; httpx2 retained. - tests/unit/test_mcp_client.py: take main's version (MCP write-tool tests). - uv.lock: regenerated against the merged pyproject. This branch carries the full OTel wiring (client _tracer, PY-11), so the test_otel.py suite passes here.
|
Update (conflict resolution + recommended canonical): Merged This branch contains everything in #39 plus the PY-11 client Suggested python merge order: (1) #43 MCP server, (2) #40 (httpx2 + streaming + OTel) — or #38 then #40 if you want httpx2 isolated first; do not merge both #38 and #40 paths, and #39 is subsumed by #40. (3) stacked follow-ups #45 ( |
Re-stack the OTel auto-instrumentation PR on the async-streaming branch so its diff shows only the OTel layer (PY-11) on top of the streaming work (PY-10). The streaming branch dropped its premature OTel scaffolding, so this merge restores _otel.py, test_otel.py, the client _tracer wiring, and the opentelemetry deps that this PR owns.
Summary
Adds async streaming helper methods for long-poll endpoints (PY-10) and extends OTel instrumentation to async client methods. Event-driven integrations can now consume alerts and incident updates via
AsyncIteratorhelpers.Acceptance Criteria
async def stream_alerts(self) -> AsyncIterator[Alert]added toAsyncHyperpingClientasync def stream_incident_updates(uuid) -> AsyncIterator[IncidentUpdate]added toAsyncHyperpingClientVerification
_async_streaming_mixin.pyandmodels/_alert_models.pyboth 100%Implementation Notes
Streaming design:
stream_alertsmaintains per-monitor baseline state to emit only state transitions (DOWN → UP, UP → DOWN). First poll populates baseline without yielding.stream_incident_updatespre-validates incident UUID for fast-fail UX;get_incidentre-validates internally as it is also a standalone public method.OTel spans: Async client methods now record OpenTelemetry spans for observability. Error recording integrated via
record_error().Pre-existing test failures: 19 OTel test failures in
test_otel.pyare PY-11 placeholders, not caused by PY-10 commits.Followups Not in This PR
src/hyperping/models/_alert_models.py:18—AlertType.DEGRADEDis defined but never emitted bystream_alerts(which only produces DOWN/UP from thedown: boolfield). Either remove before model stabilizes or document as forward-looking for future Hyperping API expansion.src/hyperping/_async_streaming_mixin.py:58—baselinedict instream_alertsis unbounded; monitors deleted from account accumulate forever. For typical bounded monitor sets negligible, but high-churn long-running listeners would see growth. TTL or periodic reconciliation can address this.tests/unit/test_streaming.py:254-291—test_stream_alerts_respects_poll_intervalandtest_stream_alerts_custom_poll_intervalcover identical behavior with different literal values (42.0 and 5.0). Consolidate to one.